package com.common.android.utils;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.util.HashMap;
import java.util.UUID;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import android.annotation.SuppressLint;
import android.text.TextUtils;
import android.text.util.Linkify;
import android.widget.TextView;

/**
 * 字符串相关工具类
 * <br>Created 2014-8-20 下午7:55:45
 * @version  1.0
 * @author   luojw		
 * @see 	 
 * Copyright(c) 2009-2014, TQ Digital Entertainment, All Rights Reserved
 */
public class StringUtils {
    
    private static HashMap<String, String> userLinkMapping = new HashMap<String, String>();
    private static final Pattern NAME_MATCHER = Pattern.compile("@.+?\\s");
    private static final String TWITTA_USER_URL = "twitta://users/";
    private static final Pattern TAG_MATCHER = Pattern.compile("#\\w+#");
    private static final String TWITTA_SEARCH_URL = "twitta://search/";
     
    /**
     * 判断某个字符串是否全是数字
     * <br>Created 2014-3-13下午3:43:14
     * @param str 源字符串
     * @return 字符串全是数字返回true，否则返回false
     * @author       cb
     */
    public static boolean isNumeric(String str){   
        if(TextUtils.isEmpty(str)) {
            return false;
        }
        Pattern pattern = Pattern.compile("[0-9]*");   
        return pattern.matcher(str).matches();      
    } 
    
    /**
     * 用正则表达式判断整型
     * <br>Created 2014-8-22 下午5:35:27
     * @param str 字符串
     * @return 字符串是整型返回true，否则返回false
     * @author       huangyx
     */
     public static boolean isIntNum(String str) {
         if (str == null || "".equals(str)) {
             return false;
         }
         Pattern pattern = Pattern.compile("-?[0-9]*");
         return pattern.matcher(str).matches();
     }
     
     /**
     * 若字符串展示的字符数超过num则将剩余的转换成省略号
     * <br>Created 2014-8-20 下午9:20:00
     * @param word 源字符串
     * @param num  展示的字符个数
     * @return 处理后的字符串
     * @author       huangyx
     */
    public static String getShortWord(String word, int num) {
        String tmp = word;
        if (word == null) {
            tmp = "";
        } else if (word.length() > num) {
            tmp = word.substring(0, num - 1) + "..";
        }
        return tmp;
    }
    
    /**
     * 根据指定分隔拆分字符串，返回字符串数组。 
     * <br>Created  2014-8-22 下午5:58:00 
     * @param str 源字符串
     * @param delim 拆分字符
     * @return 如果str和delim都不为空返回拆分后的字符串，否则返回null
     * @author       huangyx      
     */
    public static String[] strBreakWithBlank(String str, String delim) {
        if (isBlank(str) || delim == null) {
            return null;
        }
        String[] strArray = str.split("\\" + delim);
        return strArray;
    }
    
    /**
     * 判断字符串是否为空或空串,其中空串是指经过trim后字符串长度为0。 
     * <br>Created  
     * @param str 源字符串
     * @return 为null或空串返回true，否则返回false。
     * @author       huangyx 
     */
    public static boolean isBlank(String str) {
        if (str == null || (str.trim()).equals("")) {
            return true;
        }
        return false;
    }
    
    /**
     * 去掉字符串的开头和结尾空格字符
     * <br>Created 2014-8-22 下午7:41:44
     * @param str 源字符串
     * @return str不为null或者"null"字符串返回开头和结尾没有空格的字符串，否则返回false
     * @author       huangyx
     */
    public static String getFliteStr(String str) {
        if((str == null) || (str.equals("null"))) {
            return "";
        } else {
            return str.trim();
        }
    }
    
    /**
     * 用源字符编码解码字符串
     * <br>Created 2014-8-22 下午7:54:50
     * @param str 源字符串
     * @param oldCharset 旧的字符串
     * @param newCharset 新的字符串
     * @return str不为null则返回处理过的字符串，否则返回空字符串
     * @author       huangyx
     */
    public static String changeCharset(String str, String oldCharset, String newCharset) {
        if(str != null) {
            //用源字符编码解码字符串
            byte[] bs;
            try {
                bs = str.getBytes(oldCharset);
                return new String(bs, newCharset);
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
        }
        return "";
    }
    
    /**
     * 判断字符串是否为null
     * <br>Created 2014-8-22 下午7:58:39
     * @param s 源字符串
     * @return 字符串为null返回true，否则返回false
     * @author       huangyx
     */
    public static boolean isNull(String s) {
        return s == null;
    }
    
    /**
     * 判断字符串是否为null或者"null"
     * <br>Created 2014-8-22 下午7:58:39
     * @param s 源字符串
     * @return 字符串为null或者"null"返回true，否则返回false
     * @author       huangyx
     */
    public static boolean isNotNull(String s) {
        return s == null || s.equals("null");
    }
    
    /**
     * 判断字符串是否为null或者空字符串
     * <br>Created 2014-8-22 下午7:58:39
     * @param s 源字符串
     * @return 字符串为null或者空字符串返回true，否则返回false
     * @author       huangyx
     */
    public static boolean isNullEmpty(String s) {
       return s == null || s.length() == 0;
    }
    
    /**
     * 判断字符串是否为null或者空字符串或者"null"
     * <br>Created 2014-8-22 下午7:56:39
     * @param s 源字符串
     * @return 字符串是null或者空字符串或者"null"返回true，否则返回false
     * @author       huangyx
     */
    public static boolean isEmpty(String s) {
        return s == null || s.length() == 0 || s.equals("null");
    }
    
    /**
     * 获取输入流的内容
     * <br>Created 2014-8-22 下午7:58:55
     * @param is 输入流
     * @return 字符串
     * @throws IOException 
     * @author       huangyx
     */
    public static String stringifyStream(InputStream is) throws IOException {
        BufferedReader reader = new BufferedReader(new InputStreamReader(is));
        StringBuilder sb = new StringBuilder();
        String line;
        while ((line = reader.readLine()) != null) {
            sb.append(line + "\n");
        }
        return sb.toString();
    }

    
    private static final Linkify.MatchFilter NAME_MATCHER_MATCH_FILTER = 
            new Linkify.MatchFilter() {
        @Override
        public final boolean acceptMatch(final CharSequence s, final int start,final int end) {
            String name = s.subSequence(start + 1, end).toString().trim();
            boolean result = userLinkMapping.containsKey(name);
            return result;
        }
    };

    private static final Linkify.TransformFilter NAME_MATCHER_TRANSFORM_FILTER = 
            new Linkify.TransformFilter() {
        @Override
        public String transformUrl(Matcher match, String url) {
            String name = url.subSequence(1, url.length()).toString().trim();
            return userLinkMapping.get(name);
        }
    };
    
    private static final Linkify.TransformFilter TAG_MATCHER_TRANSFORM_FILTER = 
            new Linkify.TransformFilter() {
        @Override
        public final String transformUrl(Matcher match, String url) {
            if (url.length() > 1) {
                String result = url.substring(1, url.length() - 1);
                return "%23" + result + "%23";
            } else {
                return "";
            }
        }
    };
    
    public static void linkifyUsers(TextView view) {
        Linkify.addLinks(view, NAME_MATCHER, TWITTA_USER_URL,
                NAME_MATCHER_MATCH_FILTER, NAME_MATCHER_TRANSFORM_FILTER);
    }

    public static void linkifyTags(TextView view) {
        Linkify.addLinks(view, TAG_MATCHER, TWITTA_SEARCH_URL, 
                null, TAG_MATCHER_TRANSFORM_FILTER);
    }
    
    public static String getSimpleHtmlText(String text) {
        return text.replaceAll("<.*?>", "").replace("&lt;", "<")
                .replace("&gt;", ">").replace("&nbsp;", " ")
                .replace("&amp;", "&").replace("&quot;", "\"");
    }
    
    /**
     * hex字符串转换成byte数组
     * <br>Created 2014-8-22 下午8:12:08
     * @param hexString hex字符串
     * @return 如果hexString不为null和空字符串则返回byte数组，否则返回false
     * @author       huangyx
     */
    @SuppressLint("DefaultLocale")
    public static byte[] hexStringToBytes(String hexString) {  
        if (hexString == null || hexString.equals("")) {  
            return null;  
        }  
        hexString = hexString.toUpperCase();  
        int length = hexString.length() / 2;  
        char[] hexChars = hexString.toCharArray();  
        byte[] d = new byte[length];  
        for (int i = 0; i < length; i++) {  
            int pos = i * 2;  
            d[i] = (byte) (charToByte(hexChars[pos]) << 4 | charToByte(hexChars[pos + 1]));  
        }  
        return d;  
    }  
    
    /**
     * 判断字符C在第一次在”0123456789ABCDEF“出现位置
     * <br>Created 2014-8-22 下午8:13:28
     * @param c 字符
     * @return 字符C出现的位置 
     * @author       huangyx
     */
    private static byte charToByte(char c) {  
        return (byte) "0123456789ABCDEF".indexOf(c);  
    } 
   
    /**
     * 获取GUID
     * <br>Created 2014-8-26 上午10:27:48
     * @return GUID
     * @author       huangyx
     */
    public static String getGUID() {
        return UUID.randomUUID().toString();
    }
    
    /**
    * 验证是否是手机号码
    * <br>Created 2014-8-25 下午4:59:56
    * @param str 源字符串
    * @return 是手机号码返回true，否则返回false
    * @author       huangyx
    */
    public static boolean isMobile(String str) {
        if (str.equals("")) {
            return true;
        }
        Pattern pattern = Pattern.compile("1[0-9]{10}");
        Matcher matcher = pattern.matcher(str);
        return matcher.matches();
    }
    
    /**
    * 匹配国内电话号码
    * <br>Created 2014-8-25 下午5:01:28
    * @param str 源字符串
    * @return 是国内电话号码返回true，否则返回false
    * @author       huangyx
    */
    public static boolean isTelephone(String str) {
        if ("".equals(str)) {
            return true;
        }
        Pattern pattern = Pattern.compile("([0-9]{3,4}-?)?[0-9]{7,8}");
        Matcher matcher = pattern.matcher(str);
        return matcher.matches();
    }
    
    /**
    * 验证字符串是否是email
    * <br>Created 2014-8-25 下午5:02:47
    * @param str 源字符串
    * @return 是国内email返回true，否则返回false
    * @author       huangyx
    */
    public static boolean isEmail(String str) {
        if ("".equals(str)) {
            return true;
        }
        Pattern pattern = Pattern
             .compile("^([a-zA-Z0-9_\\.-])+@(([a-zA-Z0-9-])+\\.)+([a-zA-Z0-9]{2,4})+$");
    
        Matcher matcher = pattern.matcher(str);
        return matcher.matches();
    }    
}

